﻿#region Using

using System.Collections.Generic;
using System.Linq;

using Common.Enums;

using GameCommon.Base;
using GameCommon.ManagerInterfaces;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

#endregion

namespace GameCommon.Manager
{
    internal class RenderManager : IRenderManager
    {
        private readonly DrawingManager drawingManager;

        private readonly IList<RenderTarget2D> screensAsTexture; 

        private IList<IScreen> screens;

        public RenderManager(SpriteBatch spriteBatch)
        {
            this.screens = new List<IScreen>();
            this.drawingManager = new DrawingManager(spriteBatch);
            this.screensAsTexture = new List<RenderTarget2D>();
        }

        public void AddScreen(IScreen screen)
        {
            this.screens.Add(screen);
            this.screens = this.screens.OrderBy(x => x.Layer).ToList();
        }

        public void Draw(GameTime gameTime)
        {
            this.screensAsTexture.Clear();

            foreach (var screen in this.screens.ToList())
            {
                var stack = this.drawingManager.Initialize(screen.Camera);
                screen.Draw(stack, gameTime);
                stack.DrawCurrentScreenToTexture(screen.ScreenAsTexture);
                this.drawingManager.ApplyEffects(screen.Effects, screen.ScreenAsTexture);

                this.screensAsTexture.Add(screen.ScreenAsTexture);
            }

            this.drawingManager.DrawAllScreens(this.screensAsTexture);
        }

        public void RemoveScreen(IScreen screen)
        {
            this.screens.Remove(screen);
        }

        public void RemoveScreen(ScreenEnum screenEnum)
        {
            var screen = this.screens.FirstOrDefault(x => x.Screen == screenEnum);

            if (screen == null)
            {
                return;
            }

            screen.Dispose();
            this.screens.Remove(screen);
        }

        public void Update(GameTime gameTime)
        {
            foreach (var screen in this.screens.Where(x => x.IsEnabled).ToList())
            {
                screen.Update(gameTime);
            }
        }
    }
}